<template>
  <div class="q-pa-md row justify-center">
    <div class="chat-container">
      <div
        v-for="(item, index) in useMsgStores()?.currentMesg?.msgData"
        :key="index"
        :ref="el => getRiskSpreadRef(el, index)"
      >
        <q-chat-message
          :sent="item.sent"
          :text-color="item.sent ? 'white' : ''"
          :bg-color="item.sent ? 'primary' : 'amber'"
          stamp="7 minutes ago"
        >
          <template v-slot:name>{{ item.name }}</template>
          <!-- <template v-slot:stamp>7 minutes ago</template> -->
          <template v-slot:avatar>
            <img
              :class="[
                item.sent
                  ? 'q-message-avatar q-message-avatar--sent'
                  : 'q-message-avatar q-message-avatar--received'
              ]"
              :src="item.src"
            />
          </template>

          <!-- <q-spinner-dots v-if="item.loading" size="2rem" /> -->
          <q-markdown
            :src="item.text"
            :no-line-numbers="false"
            :class="'markdown' + index"
          >
          </q-markdown>
          <div class="image-container" v-if="item.images?.length">
            <div
              v-for="(image, index) in item.images"
              :key="index"
              class="image-item"
            >
              <q-img
                :src="image"
                class="preview-image"
                :alt="'Uploaded Image ' + (index + 1)"
                :ratio="1"
              />
            </div>
          </div>
          <template v-slot:stamp>
            <q-btn
              v-if="!item.sent"
              :loading="audioLoadMap[index]?.loading"
              padding="xs"
              :color="item.sent ? 'secondary' : 'deep-orange'"
              size="sm"
              @click="boFang(item, index)"
              :icon="
                audioLoadMap[index]?.loading
                  ? 'mic'
                  : audioProceedMap[index]?.loading
                  ? 'stop_circle'
                  : 'mic'
              "
            />
            <q-btn
              class="q-ml-xs"
              padding="xs"
              :color="item.sent ? 'secondary' : 'deep-orange'"
              size="sm"
              @click="copy(item)"
              icon="content_copy"
            />
          </template>
          <!-- <q-markdown :src="item.text"> </q-markdown> -->
        </q-chat-message>
      </div>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { QMarkdown } from '@quasar/quasar-ui-qmarkdown';
import '@quasar/quasar-ui-qmarkdown/dist/index.css';
import { useMsgStores } from 'src/stores/msgStores';
import {} from 'quasar';
import { watch, ref, onMounted, onUnmounted, nextTick } from 'vue';
import { audioSpeech } from 'src/api/openai.js';
import { copyToClipboard, Notify, scroll } from 'quasar';
const { getScrollTarget, setVerticalScrollPosition } = scroll;
let riskRefList = ref<HTMLElement[]>([]);
const getRiskSpreadRef = (el, index) => {
  if (el) {
    riskRefList.value[index] = el;
  }
};
// 采用元素对象(element object)
function scrollToElement(index) {
  nextTick(() => {
    let el = riskRefList.value[index];
    let target = getScrollTarget(el);
    if (el?.offsetTop && el?.scrollHeight) {
      let offset = el.offsetTop;
      let duration = 1000;
      setVerticalScrollPosition(target, offset, duration);
    }
  });
}
const audioLoadMap = ref({});
const audioProceedMap = ref({});
const msgStore = useMsgStores().currentMesg?.msgData ?? []; // 保持 store 实例
// const paramsId = useMsgStores().paramsId ?? []; // 保持 store 实例
watch(
  () => useMsgStores().paramsId,
  () => {
    scrollToElement(useMsgStores()?.currentMesg?.msgData.length - 1);
  },
  {}
);

watch(
  () => msgStore.length,
  newItems => {
    if (msgStore[newItems - 1]?.sent) {
      scrollToElement(newItems - 1);
    }
  },
  { immediate: true }
);

async function boFang(item, index) {
  // if (audio.value.src) return;
  if (audioProceedMap.value[index]?.loading && audio.value) {
    audio.value.pause();
    return;
  }
  audioLoadMap.value[index] = Object.assign({}, audioLoadMap.value[index], {
    loading: true
  });
  try {
    let response = await audioSpeech(item.text);
    const audioBlob = await response.blob();
    let audioUrl = URL.createObjectURL(audioBlob);
    audio.value.src = audioUrl; // 释放音频源
    // 监听音频播放状态
    audio.value.addEventListener('playing', () => {
      audioProceedMap.value[index] = Object.assign(
        {},
        audioProceedMap.value[index],
        {
          loading: true
        }
      );
    });

    audio.value.addEventListener('pause', () => {
      //  当音频被暂停时触发。
      audioProceedMap.value[index] = false;
    });
    audio.value.play(); // 播放音频
  } finally {
    audioLoadMap.value[index].loading = false;
  }
}

function copy(item) {
  copyToClipboard(item.text)
    .then(() => {
      console.log('拷贝成功');
      Notify.create({
        position: 'top',
        type: 'positive',
        message: '拷贝成功'
      });
    })
    .catch(() => {
      Notify.create({
        position: 'top',
        type: 'negative',
        message: '拷贝失败'
      });
    });
}

const audio = ref(new Audio());
onMounted(async () => {
  audio.value.addEventListener('ended', () => {
    // 当音频播放完毕时触发。
    audio.value.pause(); // 停止播放
    audio.value.src = ''; // 释放音频源
  });
  scrollToElement(useMsgStores()?.currentMesg?.msgData.length - 1);
});

onUnmounted(() => {
  audio.value = null;
});
</script>
<style scoped>
:deep(.q-markdown p) {
  margin: 0;
}
.my-emoji {
  vertical-align: middle;
  height: 2em;
  width: 2em;
}

.chat-container {
  max-width: 768px; /* 设置最大宽度为 768px */
  padding: 16px;
  width: 100%;
}
</style>
